package br.com.sgmf.web.validator;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.springframework.stereotype.Component;

@Component("cnpjValidator")
public class CNPJValidator implements Validator {

	@Override
	public void validate(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {
		value = removeMask(String.valueOf(value));

		if (!validaCNPJ(String.valueOf(value))) {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					"CNPJ: Erro de validação: número de CNPJ inválido", null);
			throw new ValidatorException(message);
		}
	}

	private static String removeMask(String value) {
		String cnpj = value;

		if (value != null && !value.equals("")) {
			cnpj = value.replaceAll("\\.", "").replaceAll("\\-", "")
					.replaceAll("/", "");
		}

		return cnpj;
	}

	private static boolean validaCNPJ(String cnpj) {
		if (cnpj == null || cnpj.length() != 14) {
			return false;
		}

		try {
			Long.parseLong(cnpj);
		} catch (NumberFormatException e) {
			return false;
		}

		int soma = 0;
		String cnpj_calc = cnpj.substring(0, 12);

		char chr_cnpj[] = cnpj.toCharArray();
		for (int i = 0; i < 4; i++) {
			if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
				soma += (chr_cnpj[i] - 48) * (6 - (i + 1));
			}
		}

		for (int i = 0; i < 8; i++) {
			if (chr_cnpj[i + 4] - 48 >= 0 && chr_cnpj[i + 4] - 48 <= 9) {
				soma += (chr_cnpj[i + 4] - 48) * (10 - (i + 1));
			}
		}

		int dig = 11 - soma % 11;
		cnpj_calc = String.valueOf(cnpj_calc)
				+ (dig != 10 && dig != 11 ? Integer.toString(dig) : "0");
		soma = 0;
		for (int i = 0; i < 5; i++) {
			if (chr_cnpj[i] - 48 >= 0 && chr_cnpj[i] - 48 <= 9) {
				soma += (chr_cnpj[i] - 48) * (7 - (i + 1));
			}
		}

		for (int i = 0; i < 8; i++) {
			if (chr_cnpj[i + 5] - 48 >= 0 && chr_cnpj[i + 5] - 48 <= 9) {
				soma += (chr_cnpj[i + 5] - 48) * (10 - (i + 1));
			}
		}

		dig = 11 - soma % 11;
		cnpj_calc = String.valueOf(cnpj_calc)
				+ (dig != 10 && dig != 11 ? Integer.toString(dig) : "0");

		return cnpj.equals(cnpj_calc);
	}
}